package cn.itcast.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.itcast.dao.MenuDao;
import cn.itcast.dao.UserDao;
import cn.itcast.entity.PageResult;
import cn.itcast.entity.QueryPageBean;
import cn.itcast.pojo.Menu;
import cn.itcast.pojo.Role;
import cn.itcast.pojo.User;
import cn.itcast.service.MenuService;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private UserDao userDao;

    /**
     * 分页查询
     *
     * @return
     */
    @Override
    public PageResult queryMenu(QueryPageBean queryPageBean) {
        try {
            PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
            String queryString = queryPageBean.getQueryString(); //查询条件
            //分页查询所有父级菜单
            Page<Menu> page = menuDao.queryMenuByIdList(0);
            List<Menu> result = page.getResult();

            //遍历取出父级菜单的id进行查询子级菜单
            for (Menu menu : result) {
                menu.setChildren(menuDao.queryMenuByIdList(menu.getId()));
            }
            log.debug("分页查询出的父级和子级菜单:{}", result);
            //先查询所有
            return new PageResult(page.getTotal(), result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 新增菜单表和菜单表和权限表的中间表
     *
     * @param menu
     * @return
     */
    @Override
    public Boolean addMenuAndOrder(Integer[] permissionIds, Menu menu) {
        try {
            //先添加到菜单表中
            menuDao.addMenu(menu);
            Integer id = menu.getId();
            //判断是否是创建子级菜单添加了权限
            if (permissionIds.length > 0) {
                //将保存有权限id的数组遍历
                for (Integer permissionId : permissionIds) {
                    //添加到菜单表和权限表的中间表中
                    menuDao.addMenuPermission(permissionId, id);
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 回显编辑栏的数据
     *
     * @param mid
     * @return
     */
    @Override
    public Menu queryMenuById(Integer mid) {
        return menuDao.queryMenuById(mid);
    }

    /**
     * 修改
     *
     * @param permissionIds
     * @param menu
     * @return
     */
    @Override
    public Boolean updateMenu(Integer[] permissionIds, Menu menu) {
        try {
            //修改数据
            menuDao.updateMenu(menu);
            menuDao.deleteMenuPermission(menu.getId());
            //判断是否是修改子级菜单的权限
            if (permissionIds.length > 0) {
                //将保存有权限id的数组遍历
                for (Integer permissionId : permissionIds) {
                    //添加到菜单表和权限表的中间表中
                    menuDao.addMenuPermission(permissionId, menu.getId());
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 删除
     *
     * @param mid
     * @return
     */
    @Override
    public Boolean deleteMenuById(Integer mid) {
        try {
            menuDao.deleteMenuById(mid); //删除菜单表
            //查询该菜单是否是主菜单
            Page<Menu> page = menuDao.queryMenuByIdList(mid);
            List<Menu> result = page.getResult();

            if (CollUtil.isNotEmpty(result)){
                for (Menu menu : result) {
                    menuDao.deleteMenuById(menu.getId()); //删除该父级菜单下的子级菜单
                    menuDao.deleteMenuPermission(menu.getId()); //删除中间表的数据
                    return true;
                }
            }
            menuDao.deleteMenuPermission(mid); //删除中间表的数据
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 根据username查询用户对应的菜单
     *
     * @param username
     * @return
     */
    @Override
    public Set<Menu> queryMenuListByUserName(String username) {
        //调用dao层通过用户名和密码查询数据库
        User user = userDao.queryUserByUserName(username);
        if (user == null) {
            return null;
        }

        //根据用户id查询对用的角色
        Set<Role> roleSet = userDao.queryRoleByUserId(user.getId());

        LinkedHashSet<Menu> menusParent = new LinkedHashSet<>() ;
        for (Role role : roleSet) {
            //先查询他的父级菜单
            menusParent = menuDao.queryParentMenuByRoleIdAndPid(0, role.getId());
            //遍历父级菜单取出该角色能查看的子级菜单
            for (Menu menu : menusParent) {
                List<Menu> menuChildrenList = menuDao.queryParentMenuByRoleIdAndPid(menu.getId(), role.getId()).stream().collect(Collectors.toList());
                menu.setChildren(menuChildrenList);

            }
            role.setMenus(menusParent);
        }

        //对结果进行判断
        return menusParent;
    }
}
